{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.7.4"
    },
    "colab": {
      "name": "Part 02 - Intro to Federated Learning.ipynb",
      "provenance": [],
      "collapsed_sections": []
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vwH5BFwRkQiR",
        "colab_type": "text"
      },
      "source": [
        "# পর্ব 2: ফেডারেটেড লার্নিং এর সাথে পরিচিতি\n",
        "\n",
        "শেষ বিভাগে, আমরা পয়েন্টার টেনসরগুলো সম্পর্কে শিখেছি, যা গোপনীয়তা সংরক্ষণ করে ডিপ লার্নিং এর জন্য আমাদের প্রয়োজনীয় অন্তর্নিহিত অবকাঠামো তৈরি করে। এই বিভাগে আমরা দেখবো, কিভাবে প্রাথমিক সরঞ্জামসমূহ ব্যবহার করে আমাদের প্রথম গোপনীয়তা সংরক্ষণকারী ডিপ লার্নিং এল্গোরিদম - ফেডারেটেড লার্নিং তৈরি করতে পারি।\n",
        "\n",
        "লেখক:\n",
        "- Andrew Trask - Twitter: [@iamtrask](https://twitter.com/iamtrask)\n",
        "\n",
        "অনুবাদক:\n",
        "- Sayantan Das - Github: [@ucalyptus](https://github.com/ucalyptus)\n",
        "\n",
        "- Mir Mohammad Jaber - Twitter: [@jabertuhin](https://twitter.com/jabertuhin)\n",
        "\n",
        "### ফেডারেটড লার্নিং কী?\n",
        "\n",
        "এটি ডিপ লার্নিং মডেলগুলি প্রশিক্ষণের একটি সহজ, শক্তিশালী উপায়। আপনি যদি প্রশিক্ষণের ডেটা সম্পর্কে চিন্তা করেন, এটি সর্বদা কোনও ধরণের সংগ্রহ প্রক্রিয়ার ফলাফল। লোকেরা (ডিভাইসের মাধ্যমে) বাস্তব বিশ্বে ঘটনা রেকর্ড করে ডেটা উৎপন্ন করে। সাধারণত, এই ডেটাটি একক, কেন্দ্রীয় অবস্থানে সংযুক্ত করা হয় যাতে আপনি একটি মেশিন লার্নিং মডেলকে প্রশিক্ষণ দিতে পারেন। ফেডারেটেড লার্নিং এটিকে নিজের মাথায় নিয়ে নেয়!\n",
        "\n",
        "মডেলটিতে প্রশিক্ষণ ডেটা আনার পরিবর্তে (একটি কেন্দ্রীয় সার্ভার) আপনি মডেলটিকে প্রশিক্ষণের ডেটাতে নিয়ে আসুন (এটি যেখানেই থাকুক না কেন)।\n",
        "\n",
        "ধারণাটি হলো এটি যার দ্বারা ডেটা তৈরি করছে সে কেবলমাত্র স্থায়ী অনুলিপিটির মালিক হতে পারে এবং যার ফলে এটিতে কখন কার অ্যাক্সেস রয়েছে তা নিয়ন্ত্রণ বজায় রাখে। খুব সুন্দর, তাই না?"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "PiHiPKL0kQiU",
        "colab_type": "text"
      },
      "source": [
        "# বিভাগ 2.1 - একটি খেলনা ফেডারেটেড লার্নিং-এর উদাহরণ\n",
        "\n",
        "আসুন একটি খেলনা মডেলকে কেন্দ্রিক উপায়ে প্রশিক্ষণ দিয়ে শুরু করি। মডেলগুলি পাওয়ার সাথে সাথে এটি একটি সাধারণ। আমাদের প্রথম প্রয়োজন:\n",
        "\n",
        "- একটি খেলনা ডেটাসেট\n",
        "- একটি মডেল\n",
        "- ডেটা ফিট করার জন্য একটি মডেল প্রশিক্ষণের কিছু প্রাথমিক প্রশিক্ষণের যুক্তি।\n",
        "\n",
        "দ্রষ্টব্য: যদি এই API-টি আপনার কাছে অপরিচিত হয় - তবে [fast.ai](http://fast.ai) এ যান এবং এই টিউটোরিয়ালটি চালিয়ে যাওয়ার আগে তাদের কোর্সটি গ্রহণ করুন।"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "gTojyFVskQiX",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import torch\n",
        "from torch import nn\n",
        "from torch import optim"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "I2VyKub7kQie",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "\n",
        "# A Toy Dataset\n",
        "data = torch.tensor([[0,0],[0,1],[1,0],[1,1.]], requires_grad=True)\n",
        "target = torch.tensor([[0],[0],[1],[1.]], requires_grad=True)\n",
        "\n",
        "# A Toy Model\n",
        "model = nn.Linear(2,1)\n",
        "\n",
        "def train():\n",
        "    # Training Logic\n",
        "    opt = optim.SGD(params=model.parameters(),lr=0.1)\n",
        "    for iter in range(20):\n",
        "\n",
        "        # 1) erase previous gradients (if they exist)\n",
        "        opt.zero_grad()\n",
        "\n",
        "        # 2) make a prediction\n",
        "        pred = model(data)\n",
        "\n",
        "        # 3) calculate how much we missed\n",
        "        loss = ((pred - target)**2).sum()\n",
        "\n",
        "        # 4) figure out which weights caused us to miss\n",
        "        loss.backward()\n",
        "\n",
        "        # 5) change those weights\n",
        "        opt.step()\n",
        "\n",
        "        # 6) print our progress\n",
        "        print(loss.data)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "tsAMl8ujkQij",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "train()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "rVbGv0NskQin",
        "colab_type": "text"
      },
      "source": [
        "এবং আপনার জন্য এখন প্রস্তুত! আমরা প্রচলিত পদ্ধতিতে একটি বেসিক মডেলকে প্রশিক্ষণ দিয়েছি। আমাদের সমস্ত ডেটা আমাদের স্থানীয় মেশিনে একত্রিত হয় এবং আমরা এটি আমাদের মডেলটিতে আপডেট করতে ব্যবহার করতে পারি। ফেডারেটেড লার্নিং অবশ্য এইভাবে কাজ করে না। সুতরাং, ফেডারেট লার্নিংয়ের উপায়ে এটি করার জন্য এই উদাহরণটি সংশোধন করি!\n",
        "\n",
        "সুতরাং, আমাদের কী দরকার:\n",
        "\n",
        "- কয়েকজন শ্রমিক তৈরি করুন\n",
        "- প্রতিটি কর্মীর উপর প্রশিক্ষণ ডেটার পয়েন্টার পান\n",
        "- ফেডারেট লার্নিংয়ের জন্য প্রশিক্ষণের যুক্তি আপডেট করা\n",
        "\n",
        "     নতুন প্রশিক্ষণের ধাপসমূহ:\n",
        "     - কর্মী সংশোধন করতে মডেল প্রেরণ করুন\n",
        "     - সেখানে অবস্থিত ডেটার উপর প্রশিক্ষণ করুন\n",
        "     - মডেলটি ফিরে পাবেন এবং পরবর্তী কর্মীর থেকে এর পুনরাবৃত্তি করুন"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "PJSRg5wokQiq",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import syft as sy\n",
        "hook = sy.TorchHook(torch)\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "lw-l_nm7kQiw",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# create a couple workers\n",
        "\n",
        "bob = sy.VirtualWorker(hook, id=\"bob\")\n",
        "alice = sy.VirtualWorker(hook, id=\"alice\")\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "U6P6ssF7kQi1",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# A Toy Dataset\n",
        "data = torch.tensor([[0,0],[0,1],[1,0],[1,1.]], requires_grad=True)\n",
        "target = torch.tensor([[0],[0],[1],[1.]], requires_grad=True)\n",
        "\n",
        "# get pointers to training data on each worker by\n",
        "# sending some training data to bob and alice\n",
        "data_bob = data[0:2]\n",
        "target_bob = target[0:2]\n",
        "\n",
        "data_alice = data[2:]\n",
        "target_alice = target[2:]\n",
        "\n",
        "# Iniitalize A Toy Model\n",
        "model = nn.Linear(2,1)\n",
        "\n",
        "data_bob = data_bob.send(bob)\n",
        "data_alice = data_alice.send(alice)\n",
        "target_bob = target_bob.send(bob)\n",
        "target_alice = target_alice.send(alice)\n",
        "\n",
        "# organize pointers into a list\n",
        "datasets = [(data_bob,target_bob),(data_alice,target_alice)]\n",
        "\n",
        "opt = optim.SGD(params=model.parameters(),lr=0.1)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "P_OH0s5fkQi7",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def train():\n",
        "    # Training Logic\n",
        "    opt = optim.SGD(params=model.parameters(),lr=0.1)\n",
        "    for iter in range(10):\n",
        "        \n",
        "        # NEW) iterate through each worker's dataset\n",
        "        for data,target in datasets:\n",
        "            \n",
        "            # NEW) send model to correct worker\n",
        "            model.send(data.location)\n",
        "\n",
        "            # 1) erase previous gradients (if they exist)\n",
        "            opt.zero_grad()\n",
        "\n",
        "            # 2) make a prediction\n",
        "            pred = model(data)\n",
        "\n",
        "            # 3) calculate how much we missed\n",
        "            loss = ((pred - target)**2).sum()\n",
        "\n",
        "            # 4) figure out which weights caused us to miss\n",
        "            loss.backward()\n",
        "\n",
        "            # 5) change those weights\n",
        "            opt.step()\n",
        "            \n",
        "            # NEW) get model (with gradients)\n",
        "            model.get()\n",
        "\n",
        "            # 6) print our progress\n",
        "            print(loss.get()) # NEW) slight edit... need to call .get() on loss\\\n",
        "    \n",
        "# federated averaging"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "5-8DNIr6kQjB",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "train()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "sCOHs1_2kQjF",
        "colab_type": "text"
      },
      "source": [
        "## সাবাশ!\n",
        "\n",
        "এবং voilà! ফেডারেটেড লার্নিং ব্যবহার করে আমরা এখন একটি খুব সাধারণ ডিপ লার্নিং মডেল প্রশিক্ষণ দিচ্ছি! আমরা প্রতিটি কর্মীকে মডেল প্রেরণ করি, একটি নতুন গ্রেডিয়েন্ট উৎপন্ন করি এবং তারপরে গ্রেডিয়েন্টটি আমাদের স্থানীয় সার্ভারে ফিরিয়ে আনি যেখানে আমরা আমাদের গ্লোবাল মডেলটি আপডেট করি। এই প্রক্রিয়াতে কখনই আমরা অন্তর্নিহিত প্রশিক্ষণের ডেটা দেখতে বা দেখার জন্য অনুরোধ করি না! আমরা বব এবং অ্যালিসের গোপনীয়তা সংরক্ষণ করি !!!\n",
        "\n",
        "## এই উদাহরণের ত্রুটিসমূহ\n",
        "\n",
        "সুতরাং, যদিও এই উদাহরণটি ফেডারেটড লার্নিংয়ের সাথে পরিচিতিতে দুর্দান্ত, তবে এটির এখনও কিছু বড় ত্রুটি রয়েছে। এর মধ্যে উল্লেখযোগ্য হল, যখন আমরা `Model.get ()' কল করি এবং বব বা অ্যালিসের কাছ থেকে আপডেট হওয়া মডেলটি পাই, তখন আমরা বব এবং অ্যালিসের প্রশিক্ষণের ডেটা সম্পর্কে তাদের গ্রেডিয়েন্টগুলি দেখে আসলে অনেক কিছু জানতে পারি। কিছু ক্ষেত্রে, আমরা তাদের প্রশিক্ষণের ডেটা পুরোপুরি পুনরুদ্ধার করতে পারি!\n",
        "\n",
        "তো, কী করার আছে? ঠিক আছে, প্রথম কৌশল যা লোকেরা প্রয়োগ করা থাকে তা হলো - **কেন্দ্রীয় সার্ভারে আপলোড করার আগে একাধিক ব্যক্তির মধ্যে গ্রেডিয়েন্ট গড় করা**। এই কৌশলটির জন্য পয়েন্টার টেন্সর অবজেক্টের আরও কিছু পরিশীলিত ব্যবহারের প্রয়োজন হবে। সুতরাং, পরবর্তী বিভাগে, আমরা আরও উন্নত পয়েন্টার কার্যকারিতা সম্পর্কে জানতে কিছুটা সময় নেব এবং তারপরে আমরা এই ফেডারেট লার্নিং উদাহরণটি আপগ্রেড করব।"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Q6x54BUQkQjN",
        "colab_type": "text"
      },
      "source": [
        "# অভিনন্দন !!! - সম্প্রদায় যোগদানের সময়!\n",
        "\n",
        "এই নোটবুক টিউটোরিয়ালটি সম্পন্ন করার জন্য অভিনন্দন! আপনি যদি এটি উপভোগ করেন এবং গোপনীয়তা সংরক্ষণ, এআই এবং এআই সরবরাহ চেইনের (ডেটা) বিকেন্দ্রীভূত মালিকানার দিকে আন্দোলনে যোগ দিতে চান, আপনি নিম্নলিখিত উপায়ে এটি করতে পারেন!\n",
        "\n",
        "### গিটহাবে PySyft-কে স্টার দিন\n",
        "\n",
        "আমাদের সম্প্রদায়কে সাহায্য করার সবচেয়ে সহজ উপায় হল রিপোজিটরিতে স্টার দেয়া! এটি আমরা যে দারুন সরঞ্জামগুলি তৈরি করছি তার সচেতনতা বাড়াতে সহায়তা করে।\n",
        "\n",
        "- [Star PySyft](https://github.com/OpenMined/PySyft)\n",
        "\n",
        "### আমাদের স্ল্যাকে যোগ দিন!\n",
        "\n",
        "সর্বশেষতম অগ্রগতিতে নিজেকে আপ টু ডেট রাখার সর্বোত্তম উপায় হলো আমাদের সম্প্রদায়ে যোগদান করা! আপনি [http://slack.openmined.org](http://slack.openmined.org) এ ফর্মটি পূরণ করে এটি করতে পারেন\n",
        "\n",
        "### একটি কোড প্রকল্পে যোগদান করুন!\n",
        "\n",
        "আমাদের কমিউনিটিতে অবদান রাখার সেরা উপায় হলো একজন কোড অবদানকারীতে পরিণত হওয়া। যেকোন সময় আপনি PySyft এর গিটহাব ইস্যুর পেজে যেতে পারেন এবং \"Projects\" দিয়ে বাছাই করবেন। এর মাধ্যমে আপনি যে সকল প্রজেক্টে যোগদান করতে পারবেন সেগুলোর উপরের দিকের টিকেটের ওভারভিউ পাবেন। আপনি যদি কোন প্রজেক্টে জয়েন করতে ইচ্ছুক না হোন, কিন্তু কিছুটা কোডিং করতে ইচ্ছুক সেক্ষেত্রে আপনি \"one off\" মিনি প্রজেক্টগুলো দেখতে পারেন গিটহাব ইস্যুতে \"good first issue\" চিহ্নিত ইস্যুগুলো।\n",
        "\n",
        "- [PySyft Projects](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3AProject)\n",
        "- [Good First Issue Tickets](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n",
        "### দান করুন\n",
        "\n",
        "আপনার যদি আমাদের কোডবেজে অবদান রাখারা সময় না হয়, কিন্তু এরপরও আমাদেরকে সমর্থন দিতে চান তাহলে আমাদের উন্মুক্ত সংগ্রহের সমর্থক হতে পারেন। সকল ধরনের দানের অর্থ আমাদের ওয়েব হোস্টিং এবং অন্যান্য কমিউনিটি কার্যক্রমে খরচ হয় যেমন - হ্যাকাথন, মিটাপ।\n",
        "\n",
        "[OpenMined's Open Collective Page](https://opencollective.com/openmined)"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "3g43IEsIkQjQ",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}